using System;
using System.Collections.Generic;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

using HadronData;

namespace Hadron
{
    class GameStatePlay
        : GameState
    {
        private static GameState s_gameState = new GameStatePlay();

        private Environment m_environment;
        private Hud m_hud;
        private bool m_bStartPressed;
        private bool m_bPaused;
        private GameFont m_gameFontPause;

        public static GameState Instance
        {
            get { return s_gameState; }
        }

        private GameStatePlay()
        {
        }

        public override void OnEnter()
        {
            m_environment = new Environment(m_gameContext);
            m_environment.PlayerShip = new PlayerShip(m_environment);
            m_environment.CurrentLevel = m_gameContext.World.Levels[m_gameContext.CurrentLevel];
            m_environment.InitialiseEntities();

            m_hud = new Hud(m_environment);

            m_bPaused = false;

            m_gameFontPause = new GameFont(AssetManager.Fonts.Title);
            m_gameFontPause.Colour = Color.YellowGreen;
            m_gameFontPause.Alignment = GameFontAlignment.Centre;

            // place player at entry portal
            Hadron.Entities.Portal portal = m_environment.GetNearestEntryPortal(m_environment.PlayerShip);
            m_environment.PlayerShip.Position = portal.Position;
            portal.Open = true;

            m_environment.CameraTarget = portal.Position;
        }

        public override void OnExit()
        {
            m_environment.TerminateEntities();
            m_environment = null;
            m_gameFontPause = null;
        }

        public override void Update(GameTime p_gameTime)
        {
            PlayerShip playerShip = m_environment.PlayerShip;

            // input

            // handle pause
            if (!m_bStartPressed && m_gameController.Start)
            {
                m_bPaused = !m_bPaused;
                m_bStartPressed = true;
            }
            if (!m_gameController.Start)
                m_bStartPressed = false;

            if (m_bPaused)
                return;

            // esc
            if (m_gameController.Back)
                NextState = GameStateTitle.Instance;

            // player controls
            if (playerShip.Status == PlayerShipStatus.Active)
            {
                playerShip.ForwardThruster = m_gameController.Forward;
                if (m_gameController.RotateLeft)
                    playerShip.RotationThruster = RotationThruster.CounterClockwise;
                else if (m_gameController.RotateRight)
                    playerShip.RotationThruster = RotationThruster.Clockwise;
                else
                    playerShip.RotationThruster = RotationThruster.Neutral;
                playerShip.Shield = m_gameController.Shield;
                playerShip.Fire = m_gameController.Fire;
            }

            // dev cheat 1 - next level
            if (Keyboard.GetState().IsKeyDown(Keys.F1))
                m_environment.LevelComplete = true;

            // dev cheat 2 - high score entry
            if (Keyboard.GetState().IsKeyDown(Keys.F2))
            {
                NextState = GameStateScoreName.Instance;
                m_gameContext.Score = 120000;
            }

            // dev cheat 3 - kill
            if (Keyboard.GetState().IsKeyDown(Keys.F3))
                m_environment.PlayerShip.Integrity = 0.0f;

            // dev cheat 4 - score
            if (Keyboard.GetState().IsKeyDown(Keys.F4))
                m_gameContext.Score += 2000;

            // animation
            m_environment.Update(p_gameTime);
            m_hud.Update(p_gameTime);

            // test game over
            if (m_environment.Context.Lives < 1)
                NextState = GameStateLose.Instance;

            // test level objectives
            if (m_environment.LevelComplete
                && m_environment.PlayerShip.Status == PlayerShipStatus.WarpedOut)
            {
                ++m_gameContext.CurrentLevel;
                NextState = GameStateMission.Instance;
            }
        }

        public override void Draw(SpriteBatch p_spriteBatch)
        {
            GraphicsDevice graphicsDevice = p_spriteBatch.GraphicsDevice;
            PlayerShip playerShip = m_environment.PlayerShip;

            m_environment.Draw(p_spriteBatch);
            m_hud.Draw(p_spriteBatch);

            if (m_bPaused)
            {
                p_spriteBatch.Begin();

                p_spriteBatch.Draw(AssetManager.Textures.Fade,
                    new Rectangle(0, 0, 800, 600),
                    new Color(Color.Black, 0.8f));

                m_gameFontPause.DrawString(p_spriteBatch, new Vector2(400.0f, 300.0f),
                    "Paused");

                p_spriteBatch.End();
            }
        }
    }
}
